package org.asiainfo.file.service.impl;

import io.minio.MinioClient;
import io.minio.PutObjectArgs;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.asiainfo.common.core.enums.UploadType;
import org.asiainfo.common.core.utils.MapstructUtils;
import org.asiainfo.common.core.utils.SpringUtils;
import org.asiainfo.common.core.utils.file.FileUploadUtils;
import org.asiainfo.file.config.properties.MinioProperties;
import org.asiainfo.file.domain.AttactmentInfo;
import org.asiainfo.file.domain.bo.AttactmentInfoBo;
import org.asiainfo.file.domain.vo.AttactmentInfoVo;
import org.asiainfo.file.mapper.AttactmentInfoMapper;
import org.asiainfo.file.service.AttactmentInfoService;
import org.asiainfo.file.service.FileStrategy;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

/**
 * Minio 文件策略
 *
 * @author dotor-ww
 */
@Service("minio" + FileStrategy.BASE_NAME)
@RequiredArgsConstructor
@Slf4j
public class MinioFileStrategy implements FileStrategy {

    private final MinioProperties minioProperties;

    private final MinioClient minioClient;

    private final AttactmentInfoMapper attactmentInfoMapper;

    /**
     * 上传附件
     *
     * @param attactmentBo 附件信息
     * @param file         文件
     * @return 上传结果
     */
    @Override
    public AttactmentInfoVo uploadFile(AttactmentInfoBo attactmentInfoBo, MultipartFile file) throws Exception {
        String fileName = FileUploadUtils.extractFilename(file);
        PutObjectArgs args = PutObjectArgs
            .builder()
            .bucket(minioProperties.getBucketName())
            .object(fileName)
            .stream(file.getInputStream(), file.getSize(), -1)
            .contentType(file.getContentType())
            .build();
        minioClient.putObject(args);
        // 上传路径
        String fileUrl = minioProperties.getEndpoint() + "/" + minioProperties.getBucketName() + "/" + fileName;
        AttactmentInfo attactmentInfo = SpringUtils.getBean(AttactmentInfoService.class)
            .buildAttactmentInfo(attactmentInfoBo.getAttactId(), fileUrl, file);
        attactmentInfo.setUploadType(UploadType.MINIO.getCode());
        attactmentInfo.setFileName(file.getOriginalFilename());
        attactmentInfoMapper.insertSelective(attactmentInfo);
        return MapstructUtils.convert(attactmentInfo, AttactmentInfoVo.class);
    }
}
